/*
 * GroupConnection.java    0.0.1    21/dic/2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */ 
package org.mentalsmash.tazio.transparency.interfaces;

import java.io.Serializable;

import org.jgroups.ChannelException;
import org.mentalsmash.tazio.commons.identifiers.NID;

/**
 * GroupConnection is the basic interface that has to implemented by any class that has to 
 * provide an implementation for the group communication subsystem.
 * 
 * @version 0.0.1	21/dic/2009
 * @author Enrico Savioli <savioli.enrico@gmail.com>
 */
public interface GroupConnection {
	
	/**
	 * This method is used to send a Serializable object, or a subclass of it, to the 
	 * group.
	 * <p>
	 * This method will have to encapsulate the message into a {@link TazioMessage} object 
	 * in order to grant the uniformity of messages delivered throughout the system. 
	 * </p>
	 * <p>
	 * The object is sent with an asynchronous behavior, thus it will not block in order to 
	 * wait for answers to the message.
	 * </p>
	 * 
	 * @param <T>		an object implementing the {@link Serializable} interface.
	 * @param message	the Serializable object that has to be encapsulated into a 
	 * 					{@link TazioMessage} and sent to other ReplicaManagers in the 
	 * 					group.	
	 */
	<T extends Serializable> void send(T message);
	
	/**
	 * The <code>connect()</code> method has to connect the implementor of this interface to the 
	 * group to which it will subsequently send messages.
	 * 
	 * @throws ChannelException	if the underlying communication channel to which the cluster is 
	 * 							connected is corrupted.
	 */
	public void connect() throws ChannelException;
	
	/**
	 * The <code>disconnect()</code> method has to disconnect the implementor from the underlying 
	 * group communication channel, disabling the sending and receiving of messages on it.
	 *
	 */
	public void disconnect();
	
	/**
	 * The <code>updateState()</code> has to be invoked whenever the state of a member of the cluster 
	 * should be modified.
	 * 
	 * @param id	the TazioNodeID of the member whose state has to be modified.
	 */
	public void updateState(NID id);
	
	/**
	 * The <code>getGroupState()</code> returns the instance of GroupState which represents the shared 
	 * state of the group. 
	 * 
	 * @return	the GroupState object shared by the group.
	 */
	public GroupState getGroupState();
	
	/**
	 * The <code>getNumberOfConnections()</code> method return the number of Weak Replica Managers 
	 * connected to the Replica Manager whose TazioNodeID is provided as an input parameter. 
	 * 
	 * @param id	the TazioNodeID of the RM whose number of connections is retrieved.
	 * @return		the number of WRMs connected to the RM whose TazioNodeID is provided 
	 * 				as an input parameter.
	 */
	public int getNumberOfConnections(NID id);
	
	/**
	 * The <code>getClusterName()</code> method returns the name of the cluster in a string format 
	 * to which the implementor of this interface is connected. 
	 * 
	 * @return	the name of the cluster.
	 */
	public String getClusterName();
	
	/**
	 * The <code>isConnected()</code> method checks if the object is connected to the cluster and 
	 * returns <code>true</code> in case it is actually connected.
	 * 
	 * @return	<code>true</code> if it is connected to a cluster, <code>false</code> otherwise.
	 */
	public boolean isConnected();
	
	/**
	 * The <code>getLessLoadedServer()</code> method returns the TazioNodeId of the ReplicaManager 
	 * with the lowest number of Weak Replica Managers connected to it.
	 * 
	 * @return	the TazioNodeId of the RM with the lowest number of WRMs connected to it. 
	 */
	public NID getLessLoadedMember();
	
}
